package com.mxpio.erp.equipment.service.impl;

import com.mxpio.erp.common.equipment.entity.EquipmentCategory;
import com.mxpio.erp.common.equipment.service.EquipmentCategoryService;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 设备分类Service业务层处理
 *
 * @author Cheng
 * @date 2023-06-26
 */
@Service
public class EquipmentCategoryServiceImpl extends BaseServiceImpl<EquipmentCategory> implements EquipmentCategoryService {
    /**
     * 根节点父ID的值
     */
    public static final String ROOT_PID_VALUE = "0";

    @Override
    @Transactional(readOnly = false)
    public void addEquipmentCategory(EquipmentCategory equipmentCategory) {
        equipmentCategory.setHasChild(false);
        if (StringUtils.isBlank(equipmentCategory.getPid())
                || ROOT_PID_VALUE.equals(equipmentCategory.getPid())) {
            equipmentCategory.setPid(ROOT_PID_VALUE);
        } else {
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            EquipmentCategory parent = getById(EquipmentCategory.class, equipmentCategory.getPid());
            if (parent != null) {
                //若上级节点为禁用状态该节点也为禁用状态
                equipmentCategory.setIsEnable(parent.getIsEnable());
                if (!parent.getHasChild()) {
                    this.updateTreeNodeStatus(parent.getId(), true);
                }
            }
        }
        this.save(equipmentCategory);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateEquipmentCategory(EquipmentCategory equipmentCategory) {
        EquipmentCategory entity = this.getById(EquipmentCategory.class, equipmentCategory.getId());
        if (entity == null) {
            throw new MBootException("未找到对应实体");
        }
        String old_pid = entity.getPid();
        String new_pid = equipmentCategory.getPid();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (StringUtils.isBlank(new_pid)) {
                equipmentCategory.setPid(ROOT_PID_VALUE);
            }
            if (!ROOT_PID_VALUE.equals(equipmentCategory.getPid())) {
                this.updateTreeNodeStatus(equipmentCategory.getPid(), true);
            }
        }
        this.update(equipmentCategory);
    }

    @Override
    @Transactional(readOnly = false)
    public void deleteEquipmentCategory(String id) {
        //查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (StringUtils.isNotBlank(idVal)) {
                    EquipmentCategory equipmentCategory = this.getById(EquipmentCategory.class, idVal);
                    if (equipmentCategory != null) {
                        String pidVal = equipmentCategory.getPid();
                        //查询此节点上一级是否还有其他子节点
                        Long count = JpaUtil.linq(EquipmentCategory.class).equal("pid", pidVal).notIn("id", Arrays.asList(idArr)).count();
                        if ((count == null || count == 0) && !Arrays.asList(idArr).contains(pidVal)
                                && !sb.toString().contains(pidVal)) {
                            //如果当前节点原本有子节点 现在木有了，更新状态
                            sb.append(pidVal).append(",");
                        }
                    }
                }
            }
            //批量删除节点
            Criteria c = Criteria.create().addCriterion("id", Operator.IN, Arrays.asList(idArr));
            this.deleteBatch(EquipmentCategory.class, c);
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
        } else {
            EquipmentCategory equipmentArea = getById(EquipmentCategory.class, id);
            if (equipmentArea != null) {
                this.delete(EquipmentCategory.class, id);
                this.updateOldParentNode(equipmentArea.getPid());
            }
        }

    }

    @Override
    @Transactional(readOnly = true)
    public String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }
    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<EquipmentCategory> dataList = JpaUtil.linq(EquipmentCategory.class).equal("pid", pidVal).list();
        if(dataList != null && dataList.size()>0){
            for(EquipmentCategory tree : dataList) {
                if(!sb.toString().contains(tree.getId())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(),sb);
            }
        }
        return sb;
    }

    public void updateTreeNodeStatus(String id, Boolean hasChild) {
        JpaUtil.linu(EquipmentCategory.class).set("hasChild", hasChild).equal("id", id).update();
    }

    public void updateOldParentNode(String pid) {
        if (!ROOT_PID_VALUE.equals(pid)) {
            Long count = JpaUtil.linq(EquipmentCategory.class).equal("pid", pid).count();
            if (count == null || count <= 1) {
                updateTreeNodeStatus(pid, false);
            }
        }
    }

    @Override
    @Transactional
    public EquipmentCategory getWithBranchByCode(String code) {
        Map<String, List<EquipmentCategory>> childrenMap = new HashMap<String, List<EquipmentCategory>>();
        List<EquipmentCategory> depts = JpaUtil.linq(EquipmentCategory.class).list();
        EquipmentCategory category = null;
        for (EquipmentCategory per : depts) {
            if (childrenMap.containsKey(per.getId())) {
                per.setChildren(childrenMap.get(per.getId()));
            } else {
                per.setChildren(new ArrayList<EquipmentCategory>());
                childrenMap.put(per.getId(), per.getChildren());
            }

            if (per.getPid() != null) {
                List<EquipmentCategory> children;
                if (childrenMap.containsKey(per.getPid())) {
                    children = childrenMap.get(per.getPid());
                } else {
                    children = new ArrayList<EquipmentCategory>();
                    childrenMap.put(per.getPid(), children);
                }
                children.add(per);
            }
            if (per.getCode().equals(code)){
                category = per;
            }
        }
        return category;
    }
    @Override
    public void getAllCodeFromCategory(List<String> codes, EquipmentCategory category) {
        if (category==null){
            return ;
        }
        codes.add(category.getCode());
        if (category.getChildren()!=null&&category.getChildren().size()>0){
            for (EquipmentCategory child :category.getChildren()){
                getAllCodeFromCategory(codes,child);
            }
        }
    }
    @Override
    @Transactional
    public String getFirstLevelCode(String code) {
        EquipmentCategory category = JpaUtil.linq(EquipmentCategory.class).equal("code", code).findOne();
        if (category.getPid().equals("0")||StringUtils.isBlank(category.getPid())){
            return category.getCode();
        }
        EquipmentCategory pid = JpaUtil.getOne(EquipmentCategory.class, category.getPid());
        return getFirstLevelCode(pid.getCode());
    }

    @Override
    @Transactional
    public String getSecondLevelCode(String firstEqpTypeId, String eqpTypeCode) {
        EquipmentCategory category = JpaUtil.linq(EquipmentCategory.class).equal("code", eqpTypeCode).findOne();
        if (category.getPid().equals(firstEqpTypeId)){
            return category.getCode();
        }
//        if(category.getPid().equals("0")||StringUtils.isBlank(category.getPid())){
//            return category.getCode();
//        }
        EquipmentCategory pid = JpaUtil.getOne(EquipmentCategory.class, category.getPid());

        return getSecondLevelCode(firstEqpTypeId,pid.getCode());
    }

    @Override
    @Transactional
    public String getThirdLevelCode(String secondEqpTypeId, String eqpTypeCode) {
        EquipmentCategory category = JpaUtil.linq(EquipmentCategory.class).equal("code", eqpTypeCode).findOne();
        if (category.getPid().equals(secondEqpTypeId)){
            return category.getCode();
        }
//        if(category.getPid().equals("0")||StringUtils.isBlank(category.getPid())){
//            return category.getCode();
//        }
        EquipmentCategory pid = JpaUtil.getOne(EquipmentCategory.class, category.getPid());
        return getThirdLevelCode(secondEqpTypeId,pid.getCode());
    }

    @Override
    @Transactional
    public void getChildrenCodeFromCategory(List<String> codes, EquipmentCategory category) {
        if (category==null){
            return ;
        }
        if (category.getChildren()!=null&&category.getChildren().size()>0){
            for (EquipmentCategory child :category.getChildren()){
                getAllCodeFromCategory(codes,child);
            }
        }
    }
}
